本文提及以下內容
用戶端的路由不需等待伺服器即可切換頁面。
傳統的路由,用戶需要發送請求到伺服器接收html檔案,以便導航到新的頁面。
為了確保整個App都能接收路由,在最外層importBrowserRouter
,並加入到jsx中,程式碼如下
import { createRoot } from "react-dom/client";
import { BrowserRouter } from "react-router-dom";
import App from "./App";
const container = document.getElementById("root");
const root = createRoot(container);
root.render(
<BrowserRouter>
<App />
</BrowserRouter>
);
在App.js檔案使用<Routes>
包住各個<Route>
我們在element帶入jsx組件,在path寫入要生成的url路由,另外如果是根路由可以帶入index,程式碼如下
import Count from "./Count.js";
import Test from "./Test.js";
import { Routes, Route, Link } from "react-router-dom";
function App() {
return (
<div className="App">
<Routes>
<Route path="/count" element={<Count />}></Route>
<Route path="/test" element={<Test />}></Route>
<Route index element={<div>這是首頁</div>}></Route>
</Routes>
</div>
);
}
export default App;
這時候用npm run start在url的部分輸入count就可以看到對應的jsx組件了,例如http://localhost:3001/test
使用 *
表示剩下的路由要顯示的訊息,通常用在404的頁面,程式碼範例如下
<div className="App">
<Routes>
<Route path="/count" element={<Count />}></Route>
<Route path="/test" element={<Test />}></Route>
<Route path="*" element={<div>404 Not Found</div>}></Route>
</Routes>
</div>
可以在路由內再設置路由的方式稱之為巢狀路由,如下面範例,網址列就會輸入http://localhost:3000/post/1
就能得到po文的第一頁內容了。
<div className="App">
<Routes>
<Route path="/count" element={<Count />}></Route>
<Route path="/test" element={<Test />}></Route>
<Route path="/posts/"}/>
<Route path="1" element={<div>這是第一頁</div>}></Route>
<Route path="*" element={<div>404 Not Found</div>}></Route>
</Routes>
</div>
若想要在巢狀路由當中也顯示父元素的內容,可以使用<Outlet />
,這時候輸入http://localhost:3000/post/1
就能顯示出post的jsx和/1的jsx了
如果只輸入http://localhost:3000/post/
則可顯示post的jsx
比較值得注意的是想要使用巢狀路由的話/posts後面不必帶斜線,裡面接的巢狀路由,前面也不需斜線。
然後在父路由的jsx也要寫<Outlet />
<div className="App">
<Routes>
<Route path="/count" element={<Count />}></Route>
<Route path="/test" element={<Test />}></Route>
<Route path="/posts"element={<div>這裡有很多頁<Outlet /></div>}/>
<Route path="1" element={<div>這是第一頁</div>}></Route>
<Route path="*" element={<div>404 Not Found</div>}></Route>
</Routes>
</div>
若我們在巢狀路由當中使用*
的path,可以設置在此父層路由底下的路由未匹配,簡單說可以參見以下程式碼
<div className="App">
<Routes>
<Route path="/count" element={<Count />}></Route>
<Route path="/test" element={<Test />}></Route>
<Route path="/posts"element={<div>這裡有很多頁<Outlet /></div>}/>
<Route path="1" element={<div>這是第一頁</div>}></Route>
<Route path="*" element={<div>沒有找到任何貼文</div>}>
<Route path="*" element={<div>404 Not Found</div>}></Route>
</Routes>
</div>
如果在網址列輸入http://localhost:3000/post/abcd
的話,因為沒有abcd這個路由,就會顯示沒有找到任何貼文。
如果想要將某個route後面的網址列當作參數接受的話使用冒號,在element裡面可以接要接收參數的jsx
程式碼如下
<div className="App">
<Routes>
<Route path="/count" element={<Count />} />
<Route path="/test" element={<Test />} />
<Route
path="/post"
element={
<div>
這裡有很多頁
<Outlet />
</div>
}
>
<Route path="1" element={<div>這是第一頁</div>} />
<Route path=":id" element={<Post />} />
</Route>
</Routes>
</div>
而Post的JSX如下,記得引用useParams
import React from "react";
import { useParams } from "react-router-dom";
const Post = () => {
const params = useParams();
return <div>{params.id}</div>;
};
export default Post;